package com.jackrain.nea.fc.dl.service;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.util.TypeUtils;
import com.jackrain.nea.common.PostDubbleEvent;
import com.jackrain.nea.common.PostHandleEvent;
import com.jackrain.nea.common.QueryDLUtil;
import com.jackrain.nea.config.PropertiesConf;
import com.jackrain.nea.dl.common.utils.esutil.ConvertQueryListUtil;
import com.jackrain.nea.dl.common.utils.esutil.ElasticsearchUtil;
import com.jackrain.nea.exception.NDSException;
import com.jackrain.nea.fc.dl.mapper.ViewDLPurReqMapper;
import com.jackrain.nea.fc.dl.api.ViewDLPurReqSaveCmd;
import com.jackrain.nea.fc.utils.Constants;
import com.jackrain.nea.sys.CommandAdapter;
import com.jackrain.nea.util.ApplicationContextHandle;
import com.jackrain.nea.util.RuntimeCompute;
import com.jackrain.nea.util.ValueHolder;
import com.jackrain.nea.web.face.User;
import com.jackrain.nea.web.query.DefaultWebEvent;
import com.jackrain.nea.web.query.QuerySessionImpl;
import com.jackrain.nea.web.security.Security4Utils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Set;

/**
 * 采购需求单 F4->中间表->FC
 *
 * @author wuwenxue
 * @date 2018/05/19
 **/
@Slf4j
@Component
@Service(protocol = "dubbo", validation = "true", version = "1.0", group = "cp")
public class ViewDLPurReqSaveCmdImpl extends CommandAdapter implements ViewDLPurReqSaveCmd {

    @Autowired
    PostHandleEvent postHandleEvent;

    @Autowired
    private ElasticsearchUtil esUtil;

    @Autowired
    private ConvertQueryListUtil convertQLUtil;

    @Autowired
    private PropertiesConf pconf;

    private Logger accesLogger = LoggerFactory.getLogger(Constants.ACCESS_PARAM_LOGGER);

    @Override
    public ValueHolder execute(HashMap map) throws NDSException {

        ValueHolder vh = new ValueHolder();
        JSONObject param = JSON.parseObject(JSON.toJSONStringWithDateFormat(map.get("param"),
                "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteMapNullValue), Feature.OrderedField);
        if (null == param || param.size() == 0) {
            throw new NDSException("参数格式错误！");
        }
        log.info("ViewDLPurReqSaveCmdImpl--param-->{}",param);

        ViewDLPurReqMapper viewDLPurReqMapper = ApplicationContextHandle.getBean(ViewDLPurReqMapper.class);

        JSONArray paramArray = param.getJSONArray("data");

        JSONArray errorArray = new JSONArray();
        JSONArray successIds = new JSONArray();
        JSONArray spendTimeArray = new JSONArray();
        for (int i = 0; i < paramArray.size(); i++) {
            JSONObject errorJson = new JSONObject();
            JSONObject tranJson = paramArray.getJSONObject(i);

            JSONObject zbJS = tranJson.getJSONObject("DL_T_PUR_REQUIRE_TRANSFER");
            try {
                JSONObject spendTime = new JSONObject();
                Long retObjid = null;
                //提交状态
                int status = 0;
                //终止状态
                int terminateStatus = 0;

                String userName = zbJS.getString("OPR_ECODE");
                String idList = zbJS.getString("IDLIST");
                int autoCheck = zbJS.getInteger("AUTO_CHECK");
                int isTerminate = zbJS.getInteger("ISTERMINATE");
                String bill_No = zbJS.getString("BILL_NO");

                String field = "ID,STATUS,TERMINATE_STATUS";
                JSONObject whereJS = new JSONObject();
                whereJS.put("BILL_NO", bill_No);

                HashMap isExist = QueryDLUtil.queryDL("DL_B_PUR_REQ", field, whereJS);
                if (null != isExist && isExist.size() > 0) {
                    status = TypeUtils.castToInt(isExist.get("STATUS"));
                    retObjid = TypeUtils.castToLong(isExist.get("ID"));
                    terminateStatus = TypeUtils.castToInt(isExist.get("TERMINATE_STATUS"));
                }


                //ES查询是否存在
//                JSONObject jsonObject = es(bill_No);
//                List<Long> longs = convertQLUtil.selectId(jsonObject.toString());
//                if (null != longs && longs.size() > 0) {
//                    retObjid = longs.get(0);
//                    JSONObject source = billdata(jsonObject);
//                    status = source.getInteger("STATUS");//2为已提交
//                    terminateStatus = source.getInteger("TERMINATE_STATUS");//2为已终止
//                }

                if (autoCheck != 1 && isTerminate != 1 && null != retObjid && retObjid > 0) {
                    successIds.add(idList);
                    continue;
                }

                //已保存 是否要提交
                if (null != retObjid && retObjid > 0 && autoCheck == 1 && isTerminate != 1 && status == 2) {
                    successIds.add(idList);
                    continue;
                }

                //已保存 是否要终止
                if (null != retObjid && retObjid > 0 && isTerminate == 1 && 2 == terminateStatus) {
                    successIds.add(idList);
                    continue;
                }

                if (null == userName) {
                    userName = "root";
                }
                User user = Security4Utils.getUser(userName);

                //调用保存
                if (null == retObjid || retObjid < 0) {
                    long saveStartTime = System.currentTimeMillis();
                    JSONObject resultJson = purReqSaveData(tranJson, viewDLPurReqMapper);
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlPurReq", new HashMap(16));
                    event.put("param", resultJson);
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--resultJson_save-->{}",resultJson);
                    event.setParameter("isSendMq", "N");
                    querySession.setEvent(event);
//                    String notic = "com.jackrain.nea.dl.pur.api.req.PurReqSaveCmd:1.0:dl";
                    JSONObject retJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "save");
                    double saveEndTime = (double) (System.currentTimeMillis() - saveStartTime) / 1000.0D;
                    spendTime.put("saveTime", saveEndTime);
                    spendTime.put("saveRetData", retJo);
//                    log.info("retJo=====>" + retJo.toString());
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--retJo-->{}",retJo);
                    if (!retJo.containsKey("code")){
                        throw new NDSException("保存返回值有误！无code");
                    }
                    if (retJo.containsKey("code") && (int) retJo.get("code") != 0) {
                        errorJson.put("key", idList);
                        if (null == retJo.get("message")) {
                            errorJson.put("message", "采购需求单保存调用异常");
                        } else {
                            errorJson.put("message", "采购需求单保存调用异常->" + retJo.get("message") +
                                    " data->" + retJo.get("data"));
                        }
                        errorArray.add(errorJson);
                        continue;
                    }
                    JSONObject retData = retJo.getJSONObject("data");
                    retObjid = retData.getLong("objid");
                }

                //调用提交
                if (2 != status && (autoCheck == 1 || isTerminate == 1)) {
                    long subStartTime = System.currentTimeMillis();
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlPurReq", new HashMap(16));
                    JSONObject resultJson = new JSONObject();
                    resultJson.put("objid", retObjid);
                    resultJson.put("IS_F4CHECK", "N");
                    resultJson.put("table", "DL_B_PUR_REQ");
//                    String notic = "com.jackrain.nea.dl.pur.api.req.PurReqSubmitCmd:1.0:dl";
                    event.setParameter("isSendMq", "N");
                    event.put("param", resultJson);
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--resultJson_submit-->{}",resultJson);

                    querySession.setEvent(event);
                    JSONObject retSubJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "submit");
                    double subEndTime = (double) (System.currentTimeMillis() - subStartTime) / 1000.0D;
                    spendTime.put("subEndTime", subEndTime);
//                    log.info("retSubJo=====>" + retSubJo.toString());
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--retSubJo-->{}",retSubJo);

                    if (retSubJo.containsKey("code") && (int) retSubJo.get("code") != 0) {
                        errorJson.put("key", idList);
                        if (null == retSubJo.get("message")) {
                            errorJson.put("message", "采购需求单提交调用异常");
                        } else {
                            errorJson.put("message", "采购需求单提交调用异常->" + retSubJo.get("message"));
                        }
                        errorArray.add(errorJson);
                        continue;
                    }
                }

                //调用终止
                if (isTerminate == 1) {
                    long terStartTime = System.currentTimeMillis();
                    String notic = "com.jackrain.nea.dl.pur.api.req.PurReqTerminateCmd:1.0:dl";
                    QuerySessionImpl querySession = new QuerySessionImpl(user);
                    DefaultWebEvent event = new DefaultWebEvent("dlPurReq", new HashMap(16));
                    JSONObject resultJson = new JSONObject();
                    resultJson.put("objid", retObjid);
                    resultJson.put("IS_F4CHECK", "N");
                    resultJson.put("table", "DL_B_PUR_REQ");
//                    String notic = "com.jackrain.nea.dl.pur.api.req.PurReqSubmitCmd:1.0:dl";
                    event.setParameter("isSendMq", "N");
                    event.put("param", resultJson);
                    event.setParameter("command", notic);
                    event.setParameter("webaction", "PUR_REQ_STOP");
                    querySession.setEvent(event);
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--resultJson_ter-->{}",resultJson);

                    JSONObject retTerJo = postHandleEvent.executePostHandle(resultJson, querySession, event, "webaction");
                    double terEndTime = (double) (System.currentTimeMillis() - terStartTime) / 1000.0D;
                    spendTime.put("terEndTime", terEndTime);
//                    log.info("retTerJo=====>" + retTerJo.toString());
                    accesLogger.info("ViewDLPurReqSaveCmdImpl--retTerJo-->{}",retTerJo);

                    if (retTerJo.containsKey("code") && (int) retTerJo.get("code") != 0) {
                        errorJson.put("key", idList);
                        if (null == retTerJo.get("message")) {
                            errorJson.put("message", "采购需求单终止调用异常");
                        } else {
                            errorJson.put("message", "采购需求单终止调用异常->" + retTerJo.get("message"));
                        }
                        errorArray.add(errorJson);
                        continue;
                    }
                }
                successIds.add(idList);
                spendTimeArray.add(spendTime);
            } catch (Exception e) {
                String error = "";
                if ((e instanceof NDSException)) {
                    error = e.getMessage();
                } else {
                    StringWriter sw = new StringWriter();
                    PrintWriter pw = new PrintWriter(sw);
                    e.printStackTrace(pw);
                    error = sw.toString();
                }
                String idList = zbJS.getString("IDLIST");
                errorJson.put("key", idList);
                errorJson.put("message", error);
                errorArray.add(errorJson);
            }
        }

        if (errorArray.size() > 0) {
            vh.put("error", errorArray);
            vh.put("code", -1);
        } else {
            vh.put("code", 0);
        }
        vh.put("successIds", successIds);
        vh.put("spendTime", spendTimeArray);
        return vh;
    }

    private JSONObject purReqSaveData(JSONObject tranJson, ViewDLPurReqMapper viewDLPurReqMapper) {

        JSONObject zbJS = tranJson.getJSONObject("DL_T_PUR_REQUIRE_TRANSFER");
        JSONArray itemJS = tranJson.getJSONArray("DL_T_PUR_REQUIRE_ITEM_TRANSFER");

        /*************处理明细表数据************/
        for (int j = 0; j < itemJS.size(); j++) {
            JSONObject itemJson = itemJS.getJSONObject(j);
            itemJson.put("ID", -1);
            itemJson.put("ISACTIVE", "Y");

            //商品ID
            if (null != itemJson.getString("PS_C_SKU_ECODE")) {
                String skuEcode = itemJson.getString("PS_C_SKU_ECODE");
                HashMap h = viewDLPurReqMapper.selSkuData(skuEcode);

                if (null != h && h.size() > 0) {
                    //条码ID
                    itemJson.put("PS_C_SKU_ID", h.get("ID"));
                } else {
                    throw new NDSException("SKU 查询为空！  sku编码：" + skuEcode);
                }
            }
        }

        /*************处理主表数据************/

        JSONObject newzbJson = new JSONObject();
        Set<String> keySet = zbJS.keySet();
        for (String key : keySet) {
            if ("OPR_ECODE".equals(key) || "IDLIST".equals(key)
                    || "AUTO_CHECK".equals(key) || "ISTERMINATE".equals(key)) {
                continue;
            } else {
                newzbJson.put(key, zbJS.get(key));
            }
        }

        if (zbJS.containsKey("CP_C_STORE_ECODE") && (null != zbJS.getString("CP_C_STORE_ECODE"))) {
            String ecode = zbJS.getString("CP_C_STORE_ECODE");
            HashMap h = viewDLPurReqMapper.selStoreData(ecode);

            if (null != h && h.size() > 0) {
                //店仓ID
                newzbJson.put("CP_C_STORE_ID", h.get("ID"));
            } else {
                throw new NDSException("店仓档案 查询为空_编码:" + ecode);
            }
        }
        //是否缓冲生成
        newzbJson.put("BIGINT1",2);

        JSONObject fixColumn = new JSONObject();
        fixColumn.put("DL_B_PUR_REQ", newzbJson);
        fixColumn.put("DL_B_PUR_REQ_ITEM", itemJS);

        JSONObject resultJson = new JSONObject();
        resultJson.put("objid", -1);
        resultJson.put("IS_F4CHECK", "N");
        resultJson.put("fixcolumn", fixColumn);
        resultJson.put("table", "DL_B_PUR_REQ");

        log.debug("resultJson==>" + resultJson.toString());

        return resultJson;
    }

    /**
     * ES查询
     *
     * @param billNo 单据编号
     * @return id
     */
    public JSONObject es(String billNo) {
        JSONObject bill_no = esUtil.generateMatch("BILL_NO", billNo);
        List<JSONObject> terms = esUtil.packageTerm(bill_no);
        String esIndex = pconf.getProperty("DL_B_PUR_REQ");
//        List<Long> longs = null;
        JSONObject jsonObject = null;
        try {
            jsonObject = esUtil.searchAllDataByTerms(esIndex,
                    esIndex, "1", "10000", terms);
            log.debug("es_jsonObject->" + jsonObject);
//            longs = convertQLUtil.selectId(jsonObject.toString());
        } catch (IOException e) {
            log.error(e.getMessage());
        }
        return jsonObject;
    }

    private JSONObject billdata(JSONObject esData) {
        JSONObject hits = esData.getJSONObject("hits");
        JSONArray hitsArray = hits.getJSONArray("hits");
        JSONObject sourceJson = hitsArray.getJSONObject(0);
        JSONObject source = sourceJson.getJSONObject("_source");

        return source;
    }


}
